/**
 * 帧引擎
 */
if ('function' != typeof LBUtility) {

    throw   'Little Bee core lib not import';
}

/**
 * 构造函数
 */
var Frame   = function (options) {

    this._id    = ++ Frame._IDSeed;
    this.initialize(options);
};

Frame._IDSeed   = 0;
Frame._ready	= false;
Frame.eventNameList	= [
	'frame.start',
	'frame.loop',
	'frame.enterFrame',
	'frame.pause',
	'frame.resume',
	'frame.stop'
];

Frame.isOwnEventName	= function (eventName) {
	
	for (var offset = 0;offset < Frame.eventNameList.length;offset ++) {
		
		if (Frame.eventNameList[offset] == eventName) {
			
			return	true;
		}
	}
	
	return	false;
}

/**
 * 注册事件名
 */
Frame.initailize	= function () {
	
	if (Frame._ready) {
		
		return	;
	}

	for (var offset = 0;offset < Frame.eventNameList.length;offset ++) {
		
		LBEvent.registName(Frame.eventNameList[offset]);
	}

	Frame._ready	= true;
}

LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEventDispatcher.js');
LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEventListener.js');
LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEvent.js');

/**
 * 初始化
 */
Frame.prototype.initialize  = function (options) {

	this._status		= 'stoped';
    this._currentFPS    = 'undefined' != typeof options && 'undefined' != typeof options.FPS
						? options.FPS
						: 0;
    this._currentTime   = -1;
    this._currentFrame  = -1;
    this._lastLoopTime  = -1;
}

/**
 * {{{帧引擎行为控制 开始
 */

/**
 * 帧引擎启动
 */
Frame.prototype.start   = function () {

	if ('stoped' != this._status) {
		
		throw	"Frame not stoped";
	}
	
	this._status		= 'running';
    this._lastLoopTime  = this._currentTime = (new Date()).getTime();
    LBEventDispatcher
        .getInstance()
        .addEventListener(
            new LBEvent({
                "name"      : 'frame.loop',
                "target"    : this,
                "id"        : this._id
            }),
            this._loopCallback
        );
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.loop',
        "target"    : this,
        "id"        : this._id
    }));
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.start',
        "target"    : this,
        "id"        : this._id
    }));
}

/**
 * 帧引擎暂停
 */
Frame.prototype.pause	= function () {

	if ('running' != this._status) {
		
		throw	"Frame not running";
	}
	
	this._status		= 'paused';
    this._lastLoopTime  = this._currentTime = (new Date()).getTime();
    LBEventDispatcher
        .getInstance()
        .removeEventListener(
            new LBEvent({
                "name"      : 'frame.loop',
                "target"    : this,
                "id"        : this._id
            }),
            this._loopCallback
        );
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.pause',
        "target"    : this,
        "id"        : this._id
    }));
}

/**
 * 帧引擎恢复
 */
Frame.prototype.resume	= function () {

	if ('paused' != this._status) {
		
		throw	"Frame not paused";
	}
	
	this._status		= 'running';
    this._lastLoopTime  = this._currentTime = (new Date()).getTime();
    LBEventDispatcher
        .getInstance()
        .addEventListener(
            new LBEvent({
                "name"      : 'frame.loop',
                "target"    : this,
                "id"        : this._id
            }),
            this._loopCallback
        );
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.loop',
        "target"    : this,
        "id"        : this._id
    }));
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.resume',
        "target"    : this,
        "id"        : this._id
    }));
}

/**
 * 帧引擎停止
 */
Frame.prototype.stop	= function () {
	
	if ('running' == this._status) {

		LBEventDispatcher
			.getInstance()
			.removeEventListener(
				new LBEvent({
					"name"      : 'frame.loop',
					"target"    : this,
					"id"        : this._id
				}),
				this._loopCallback
			);
	}
    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.stop',
        "target"    : this,
        "id"        : this._id
    }));
	this.initialize({
		"FPS"	: this._currentFPS
	});
}

/**
 * 修改帧频
 */
Frame.prototype.changeFPS	= function (FPS) {
	
	if (FPS >= 0) {
	
		this._currentFPS	= FPS;
	}
}

/**
 * 帧引擎行为控制 结束}}}
 */


/**
 * {{{事件控制 开始
 */

/**
 * 增加事件
 */
Frame.prototype.addEventListener    = function (eventName, listener, priority) {

	if (!Frame.isOwnEventName(eventName)) {
		
		throw	"ownner of this event name '" + eventName + "' not Frame";
	}

    LBEventDispatcher
        .getInstance()
        .addEventListener(
            new LBEvent({
                "name"      : eventName,
                "target"    : this,
                "id"        : this._id
            }),
            listener,
            priority
        );
}

/**
 * 删除事件
 */
Frame.prototype.removeEventListener = function (eventName, listener, priority) {

	if (!Frame.isOwnEventName(eventName)) {
		
		throw	"ownner of this event name '" + eventName + "' not Frame";
	}

    LBEventDispatcher
        .getInstance()
        .removeEventListener(
            new LBEvent({
                "name"      : eventName,
                "target"    : this,
                "id"        : this._id
            }),
            listener,
            priority
        );
}

/**
 * 事件控制 结束}}}
 */

/**
 * 事件检测回路 不对外开放
 */
Frame.prototype._loopCallback   = function (event) {

    var me  = event._target;
    me._currentTime     = (new Date()).getTime();

    if (me._currentFPS > 0 && me._lastLoopTime + (1000 / me._currentFPS) <= me._currentTime) {

        me._lastLoopTime    = me._currentTime;
        ++ me._currentFrame;

        LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
            "name"      : 'frame.enterFrame',
            "target"    : me,
            "id"        : me._id
        }));
    }

    LBEventDispatcher.getInstance().triggerEvent(new LBEvent({
        "name"      : 'frame.loop',
        "target"    : me,
        "id"        : me._id
    }));

}






